// #include <iostream>
#include <iostream>
// #include "LogFormat.hpp"
// #include "LogMessage.hpp"
// #include "LogLevel.hpp"
// #include "LogSink.hpp"
// #include <iostream>
// #include <thread>
// #include "Logger.hpp"
// #include "Buffer.hpp"
// #include "Mylib.h"

// void test()
// {

//     LOG_D("我是一条测试日志！！！");
//     LOG_I("我是一条测试日志！！！");
//     LOG_W("我是一条测试日志！！！");
//     LOG_E("我是一条测试日志！！！");
//     LOG_F("我是一条测试日志！！！");

//     size_t count = 0;
//     while (count < 50000)
//     {
//         LOG_F("测试日志-%d", count++);
//         // usleep(1000);
//     }
// }
// int main()
// {
//     std::unique_ptr<log::LoggerBuilder> builder(new log::GlobalLoggerBuilder());
//     builder->BuildLoggerName("root");
//     builder->BuildLoggerType(log::LoggerType::LOGGER_SYNC);
//     builder->BuildLoggerLevel(log::LogLevel::level::WARNING);
//     builder->BuildLoggerSinks<log::LogToStdout>();
//     builder->BuildAsynceUnsafeType();
//     builder->BuildLoggerSinks<log::LogToFile>("./logfile/testdefine.log");
//     builder->build();
//     test();
//     return 0;
// }
/*
    //客户端支持扩展,实现日志落地的方向

*/
// enum class TimeGap
// {
//     GAP_SECOND,
//     GAP_MINUTE,
//     GAP_HOUR,
//     GAP_DAY
// };
// class LogToRollFileByTime : public log::LogTo
// {
// public:
//     LogToRollFileByTime(std::string basename, TimeGap time_gap)
//         : _basename(basename)
//     {
//         switch (time_gap)
//         {
//         case TimeGap::GAP_SECOND:
//             _gap_size = 1;
//             break;
//         case TimeGap::GAP_MINUTE:
//             _gap_size = 60;
//             break;
//         case TimeGap::GAP_HOUR:
//             _gap_size = 3600;
//             break;
//         case TimeGap::GAP_DAY:
//             _gap_size = 3600 * 24;
//             break;
//         }
//         _cur_gap = log::util::Date::NowTime() % _gap_size == 0 ? log::util::Date::NowTime() : log::util::Date::NowTime() % _gap_size;

//         std::string pathname = CreateFile();
//         // 1:创建文件所在的目录
//         log::util::File::Mkdir(log::util::File::GetFileDirectory(pathname));
//         _ofs.open(pathname, std::ios::binary | std::ios::app);
//         assert(_ofs.is_open());
//     }
//     void WriteLog(const char *str, size_t len)
//     {
//         // 判断当前时间需不需要创建新的文件
//         time_t cur = log::util::Date::NowTime();
//         if (cur % _gap_size != _cur_gap)
//         {
//             _ofs.close();
//             std::string pathname = CreateFile();
//             _ofs.open(pathname, std::ios::binary | std::ios::app);
//             assert(_ofs.is_open());
//         }
//         _ofs.write(str,len);
//         assert(_ofs.good());
//     }

// private:
//     // 创建文件名 basename+时间的形式
//     std::string CreateFile()
//     {
//         // 获取时间戳
//         time_t timestamp = time(nullptr);
//         struct tm t;
//         localtime_r(&timestamp, &t); // 将时间戳转化为日历那样的时间格式
//         std::string filename = _basename;
//         std::stringstream ss;
//         t.tm_year += 1900;
//         t.tm_mon += 1;
//         ss << t.tm_year << "-" << t.tm_mon << "-" << t.tm_mday << " [" << t.tm_hour << ":" << t.tm_min << ":" << t.tm_sec << "] ";
//         ss << ".log";
//         filename += ss.str();
//         return filename;
//     }

// private:
//     std::string _basename;
//     std::ofstream _ofs;
//     time_t _cur_gap;  // 现在的时间段
//     size_t _gap_size; // 以gap为间隔进行建立文件
// };

#include "Logger.hpp"
#include "Mylib.h"
#include <chrono>

void bench(const std::string &loger_name, size_t thread_num, size_t msglen, size_t msg_count)
{
    log::Logger::ptr lp = log::GetLogger(loger_name);
    if (lp.get() == nullptr)
        return;
    std::string msg(msglen, '1');
    size_t msg_count_per_thread = msg_count / thread_num;
    std::vector<double> cost_time(thread_num);
    std::vector<std::thread> threads;
    std::cout << "输入线程数量: " << thread_num << std::endl;
    std::cout << "输出日志数量: " << msg_count << std::endl;
    std::cout << "输出日志大小: " << msglen * msg_count / 1024 << "KB" << std::endl;
    for (int i = 0; i < thread_num; i++)
    {
        threads.emplace_back([&, i]()
                             {
            auto start = std::chrono::high_resolution_clock::now();
            for(size_t j = 0; j < msg_count_per_thread; j++) {
                lp->FATAL("%s", msg.c_str());
            }
            auto end = std::chrono::high_resolution_clock::now();
            auto cost = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
            cost_time[i] = cost.count();
            auto avg = msg_count_per_thread / cost_time[i];
            std::cout << "线程" << i << "耗时: " << cost.count() << "s" << " 平均：" << (size_t)avg << "/s\n"; });
    }
    for (auto &thr : threads)
    {
        thr.join();
    }
    double max_cost = 0;
    for (auto cost : cost_time)
        max_cost = max_cost < cost ? cost : max_cost;
    std::cout << "总消耗时间: " << max_cost << std::endl;
    std::cout << "平均每秒输出: " << (size_t)(msg_count / max_cost) << "条日志" << std::endl;
    std::cout << "平均每秒输出: " << (size_t)(msglen * msg_count / max_cost / 1024 / 1024) << "MB" << std::endl;
}
void sync_bench_thread_log(size_t thread_count, size_t msg_count, size_t msglen)
{
    static int num = 1;
    std::string logger_name = "sync_bench_logger" + std::to_string(num++);
    LOG_I("************************************************");
    LOG_I("同步日志测试: %d threads, %d messages", thread_count, msg_count);

    log::GlobalLoggerBuilder::ptr lbp(new log::GlobalLoggerBuilder);
    lbp->BuildLoggerName(logger_name);
    lbp->BuildLoggerFormatter("%m");
    lbp->BuildLoggerSinks<log::LogToFile>("./logs/sync.log");
    lbp->BuildLoggerType(log::LoggerType::LOGGER_SYNC);
    lbp->build();
    bench(logger_name, thread_count, msglen, msg_count);
    LOG_I("************************************************");
}
void async_bench_thread_log(size_t thread_count, size_t msg_count, size_t msglen)
{
    static int num = 1;
    std::string logger_name = "async_bench_logger" + std::to_string(num++);
    LOG_I("************************************************");
    LOG_I("异步日志测试: %d threads, %d messages", thread_count, msg_count);

    log::GlobalLoggerBuilder::ptr lbp(new log::GlobalLoggerBuilder);
    lbp->BuildLoggerName(logger_name);
    lbp->BuildLoggerFormatter("%m");
    lbp->BuildLoggerSinks<log::LogToFile>("./logs/async.log");
    lbp->BuildLoggerType(log::LoggerType::LOGGER_ASYNC);
    lbp->build();
    bench(logger_name, thread_count, msglen, msg_count);
    LOG_I("************************************************");
}
void bench_test()
{
    /*异步日志输出*/
    async_bench_thread_log(1, 1000000, 100);
    async_bench_thread_log(5, 1000000, 100);
    // 同步写日志
    sync_bench_thread_log(1, 1000000, 100);
    sync_bench_thread_log(5, 1000000, 100);
}

int main(int argc, char *argv[])
{
    bench_test();

    return 0;
}